package org.jordens.jdbcspy;

import java.io.*;
import java.util.*;

/**
 * A general purpose properties handler for System or file-based properties.
 *
 * You can specify JDBCSpy properties in either of two ways:
 * - jdbcspy.properties file
 * - as System properties
 *
 * It's important to note that a System property will explicitly overwrite a property
 * specified in the jdbcspy.properties file. 
 *
 * Valid properties are:
 * - JDBCSpyDriver.resetInterval
 * - JDBCSpyDriver.logFile
 * - JDBCSpyDriver.wrappedDriver  
 *
 * @author Adam Jordens
 */
public class JDBCSpyProperties
{
    public static final String JDBCSPY_RESET_INTERVAL = "JDBCSpyDriver.resetInterval";
    public static final String JDBCSPY_LOG_FILE = "JDBCSpyDriver.logFile";
    public static final String JDBCSPY_WRAPPED_DRIVER = "JDBCSpyDriver.wrappedDriver";

    private static final JDBCSpyProperties instance = new JDBCSpyProperties();

    private final String WRAPPED_DRIVER;
    private final Long RESET_INTERVAL;
    private final File LOG_FILE;

    /**
     * Do not instantiate JDBCSpyProperties.
     */
    private JDBCSpyProperties()
    {
        Properties localProperties = new Properties();

        try
        {
            ClassLoader contextClassLoader =
                    Thread.currentThread().getContextClassLoader();

            InputStream asStream =
                    contextClassLoader.getResourceAsStream("jdbcspy.properties");
            
            localProperties.load(asStream);
        }
        catch (Exception e)
        {
            // do nothing
        }

        Properties systemProperties = System.getProperties();
        copyProperties(
                systemProperties, localProperties,
                JDBCSPY_RESET_INTERVAL, JDBCSPY_LOG_FILE, JDBCSPY_WRAPPED_DRIVER);

        Long resetInterval = null;
        File logFile = null;

        String interval = localProperties.getProperty(JDBCSPY_RESET_INTERVAL);
        if (interval != null)
        {
            resetInterval = Long.valueOf(interval);
        }

        String file = localProperties.getProperty(JDBCSPY_LOG_FILE);
        if (file != null)
        {
            logFile = new File(file);
        }


        this.WRAPPED_DRIVER = localProperties.getProperty(JDBCSPY_WRAPPED_DRIVER);
        this.RESET_INTERVAL = resetInterval;
        this.LOG_FILE = logFile;
    }

    /**
     * @param source Source instance to copy property values from
     * @param target Target instance to copy property values to
     * @param propertyNames Property names that if present in source should be copied to target
     */
    private void copyProperties(Properties source, Properties target, String ... propertyNames)
    {
        for (String propertyName : propertyNames)
        {
            Object obj = source.getProperty(propertyName);
            if (obj != null)
            {
                target.put(propertyName, obj);
            }
        }
    }

    /**
     * Getter for property 'instance'.
     *
     * @return Value for property 'instance'.
     */
    public static JDBCSpyProperties getInstance()
    {
        return instance;
    }

    /**
     * Getter for property 'WRAPPED_DRIVER'.
     *
     * @return Value for property 'WRAPPED_DRIVER'.
     */
    public String getWrappedDriver()
    {
        return WRAPPED_DRIVER;
    }

    /**
     * Getter for property 'RESET_INTERVAL'.
     *
     * @return Value for property 'RESET_INTERVAL'.
     */
    public Long getResetInterval()
    {
        return RESET_INTERVAL;
    }

    /**
     * Getter for property 'LOG_FILE'.
     *
     * @return Value for property 'LOG_FILE'.
     */
    public File getLogFile()
    {
        return LOG_FILE;
    }

    /**
     * {@inheritDoc}
     */
    public String toString()
    {
        return "JDBCSpyProperties[logFile=" + getLogFile() +
               ", resetInterval=" + getResetInterval() +
               ", wrappedDriver=" + getWrappedDriver() + "]";
    }
}
